#include "Character.h"
#include "Map.h"

Character::Character()
{
}

Character::~Character()
{
}

void Character::Load()
{
	mSprite.Load("hotdog.png");
}

void Character::Unload()
{
	mSprite.Unload();
}

void Character::Update(float deltaTime, const Map& map)
{
	const float kSpeed = 500.0f; 
	//instead of moving position directly with keys
	//modify displacement (take collision into account) before applying
	float displacementX = 0.0f;

	////////////////////////HORIZONTAL////////////////////////////////////
	if(Input_IsKeyDown(Keys::RIGHT))
	{
		displacementX = kSpeed * deltaTime;
	}
	else if(Input_IsKeyDown(Keys::LEFT))
	{
		displacementX = -kSpeed * deltaTime;
	}

	//shift bounding box to create projection using displacement in x-axis
	SRect boundingBox = GetBoundingBox() + SVector2(displacementX, 0.0f);
	if(displacementX > 0.0f)
	{
		//CHECK RIGHT line segment of bounding box if moving right (positive displacement)
		SLineSegment segment = boundingBox.GetRightSegment();
		
		//check  line segment against map
		SRect collisionBox;
		if(map.TestCollision(segment, collisionBox))
		{
			//prevent movement if there is collision:
			//(characters position must be at least the bounding box width away)
			displacementX -= boundingBox.max.x - collisionBox.min.x;
			mPosition.x += (int)displacementX +5.0f;
		}
		else
		{
			mPosition.x += (int)displacementX;
		}
		
	}

	else if (displacementX < 0.0f)
	{
		//TO-DO:
		//CHECK LEFT line segment if moving left (negative displacement)
		SLineSegment segment = boundingBox.GetLeftSegment();

		SRect collisionBox;
		if(map.TestCollision(segment, collisionBox))
		{
			displacementX += collisionBox.max.x - boundingBox.min.x;
			mPosition.x += (int)displacementX + 5.0f;
		}
		else
		{
			mPosition.x += (int)displacementX;
		}
	}

	/////////////////////////////////VERTICAL////////////////////////////////

	float displacementY = 0.0f;

	if(Input_IsKeyDown(Keys::UP))
	{
		displacementY = -kSpeed * deltaTime;
	}
	else if(Input_IsKeyDown(Keys::DOWN))
	{
		displacementY = kSpeed * deltaTime;
	}

	SRect boundingBoxY = GetBoundingBox() + SVector2(displacementY, 0.0f);

	if(displacementY > 0.0f)
	{
		SLineSegment segment = boundingBoxY.GetBottomSegment();
		
		SRect collisionBox;
		if(map.TestCollision(segment, collisionBox))
		{
			displacementY -= boundingBoxY.max.y - collisionBox.min.y;
			mPosition.y += (int)displacementY + 5.0f;
		}
		else
		{
			mPosition.y += (int)displacementY;
		}
		
	}

	else if (displacementY < 0.0f)
	{
		SLineSegment segment = boundingBoxY.GetTopSegment();

		SRect collisionBox;
		if(map.TestCollision(segment, collisionBox))
		{
			displacementY += collisionBox.max.y - boundingBoxY.min.y;
			mPosition.y += (int)displacementY + 5.0f;
		}
		else
		{
			mPosition.y += (int)displacementY;
		}
	}
}

void Character::Render(const SVector2& viewOffset) 
{
	//offset to make up for off position, move from corner to the center
	int width = mSprite.GetWidth();
	int height = mSprite.GetHeight();

	SVector2 offset(width * 0.5f, height * 0.5f);

	//add view offset to move from local to global space (keep character in center of screen space)
	SVector2 renderPosition = mPosition - offset - viewOffset; 

	mSprite.SetPosition(renderPosition);

	mSprite.Render();
}

SRect Character::GetBoundingBox() const
{
	//need to create an approximate shape for collision etc.
	SRect boundingBox;
	
	//defining x and y minimums of bounding box
	//using magic numbers containing size of content on sprite
	boundingBox.min.x = mPosition.x - 32.0f;
	boundingBox.max.x = mPosition.x + 32.0f;
	boundingBox.min.y = mPosition.y - 60.0f;
	boundingBox.max.y = mPosition.y + 60.0f;

	//moving in positive x, check right line segment of box etc.

	return boundingBox;
}